package main

import "fmt"

func main() {
	/* 创建channel并赋值 */
	var ch chan int                      //声明一个元素为int类型的channel类型变量,默认值为nil
	ch1 := make(chan int)                //声明元素类型为int的channel类型变量,属于无缓冲channel
	ch2 := make(chan int, 1)             //声明元素类型为int的channel类型变量,并赋初值,属于带缓冲channel
	fmt.Println(ch, cap(ch), len(ch))    //nil 0 0
	fmt.Println(ch1, cap(ch1), len(ch1)) //0xc00001a2a0 0 0
	fmt.Println(ch2, cap(ch1), len(ch1)) //0xc000078000 0 0

	/* 无缓冲区channel */
	// 将 13 发送到 无缓冲channel 类型变量ch1中
	// ch1 <- 13 //fatal error: all goroutines are asleep - deadlock!
	go func() {
		ch1 <- 13 // 将发送操作放入一个新goroutine中执行
	}()
	// 从 无缓冲channel 类型变量ch1 中接收数据 并存储到 变量n中
	n := <-ch1
	fmt.Println(n) // 13

	/* 带缓冲区channel */
	// s := <-ch2 // 由于此时ch2的缓冲区中无数据，因此对其进行接收操作将导致goroutine挂起
	ch2 <- 17 // 将 17 发送到 带缓冲channel 类型变量ch2中, OK
	// ch2 <- 18 // 由于此时ch2中缓冲区已满，再向ch2发送数据将导致goroutine挂起.引发fatal error: all goroutines are asleep - deadlock!

	fmt.Printf("ch2的容量:%v,元素个数:%v \n", cap(ch2), len(ch2)) //ch2的容量:1,元素个数:1
	fmt.Println(<-ch2)                                     // 17
	fmt.Printf("ch2的容量:%v,元素个数:%v \n", cap(ch2), len(ch2)) //ch2的容量:1,元素个数:0

	/* 只发送 channel 类型和只接收 channel 类型 */
	ch3 := make(chan<- int, 1) // 只发送channel类型
	ch4 := make(<-chan int, 1) // 只接收channel类型
	// 这里打印的是可以分别代表两个通道的指针的16进制表示
	fmt.Printf("单向channel的指针: %v, %v \n", ch3, ch4) //单向channel的指针: 0xc00001c4d0, 0xc00001c540
	//<-ch3     // invalid operation: cannot receive from send-only channel ch3 (variable of type chan<- int)
	//ch4 <- 13 // invalid operation: cannot send to receive-only channel ch4 (variable of type <-chan int)
}
